package com.matt.controller.web.care;

import com.google.common.collect.ImmutableMap;
import com.matt.commons.dto.sso.StaffDTO;
import com.matt.commons.exception.BusinessException;
import com.matt.commons.model.StatusResponse;
import com.matt.commons.page.PagerQuery;
import com.matt.controller.pad.care.CareBaseController;
import com.matt.domain.Children;
import com.matt.domain.care.*;
import com.matt.foundation.model.ErrorCode;
import com.matt.foundation.vo.care.HLDailyRecordVO;
import com.matt.service.ClassesService;
import com.matt.service.care.*;
import com.matt.service.care.po.HLDailyRecordPO;
import com.tuo51.foudation.utils.DateUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.web.bind.annotation.*;

import java.util.*;
import java.util.stream.Collectors;

import static com.matt.foundation.constant.RequestConstant.TICKET;

@RestController
@RequestMapping("/web/record/daily")
@Slf4j
@Api(tags = "护理记录 - 宝宝一日")
public class WebCareDailyController extends CareBaseController<HLDailyRecord, HLDailyRecordService, HLDailyRecordPO> {

    @Autowired
    HLSleepRecordService sleepRecordService;

    @Autowired
    HLFeedingRecordService feedingRecordService;

    @Autowired
    HLPottyRecordService pottyRecordService;

    @Autowired
    HLMedicationRecordService medicationRecordService;

    @Autowired
    ClassesService classesService;

    @Autowired
    HLMoreRecordService moreRecordService;

    @Autowired
    HLTemperatureRecordService temperatureRecordService;

    @Autowired
    public void setBaseService(HLDailyRecordService service){
        super.setBaseService(service);
    }

    @Override
    public StatusResponse add(@RequestHeader(TICKET) String ticket, HLDailyRecordPO param){
        return StatusResponse.error(ErrorCode.CANNOT_MODIFY_PLAN, "你应该用不到这个接口");
    }

    @ApiOperation(value = "获取多宝宝的综合列表")
    @GetMapping("/multiple")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "formData", name = "daily", value = "时间", required = true, dataType = "date"),
    })
    public StatusResponse get(@RequestHeader(TICKET) String ticket, String classId, String[] childIds,Date daily, Boolean diaper, PagerQuery pagerQuery){
        StaffDTO staff = cache.getStaff(ticket);
        if (daily == null){
            throw new BusinessException(ErrorCode.DAY_TOO_BIG, "请指定查询日期");
        }

        Page<HLDailyRecord> ret = null;
        if (childIds == null && StringUtils.isNotEmpty(classId)){
            Page<Children> page = classesService.getChildIdsByClassesId(staff.getAreaId(), classId, pagerQuery);

            childIds = page.getContent().stream().map(o->o.getId()).toArray(String[]::new);

            List<HLDailyRecord> records = baseService.getAllByChildIdsAndDaily(staff.getAreaId(), staff.getId(), childIds, daily);

            Map<String, HLDailyRecord> cache = records.stream().collect(Collectors.toMap(HLDailyRecord::getChildId, o -> o));

            ret = page.map(o-> {
                HLDailyRecord r = cache.get(o.getId());
                if (r == null){
                    r = new HLDailyRecord();
                    r.setAreaId(o.getAreaId());
                    r.setChildId(o.getId());
                    r.setChildName(o.getName());
                }
                return r;
            });
        }else if (childIds != null){
            List<HLDailyRecord> records = baseService.getAllByChildIdsAndDaily(staff.getAreaId(), staff.getId(), childIds, daily);
            ret = new PageImpl<HLDailyRecord>(records);
        }else{
            return   StatusResponse.success(new PageImpl<>(new ArrayList<>(), PageRequest.of(pagerQuery.getPageNum(), pagerQuery.getPageSize()), 0));
//            throw new BusinessException("请指定查询班级或指定宝宝列表");
        }

        Map<String, Object> param = diaper == null? new HashMap<>() : ImmutableMap.of("diaper", diaper);

        if (ret.getContent().size() > 0){
            childIds = ret.getContent().stream().map(o->o.getChildId()).toArray(String[]::new);;

            //响应的page ids
            List<HLFeedingRecord> feedingRecords  = feedingRecordService.dailyRecords(staff.getAreaId(), staff.getId(), childIds, daily, param);
            List<HLSleepRecord> sleepRecords  = sleepRecordService.dailyRecords(staff.getAreaId(), staff.getId(), childIds, daily, param);
            List<HLPottyRecord> pottyRecords  = pottyRecordService.dailyRecords(staff.getAreaId(), staff.getId(), childIds, daily, param);
            List<HLMedicationRecord> medicationRecords  = medicationRecordService.dailyRecords(staff.getAreaId(), staff.getId(), childIds, daily, param);
            List<HLTemperatureRecord> temperatureRecords  = temperatureRecordService.dailyRecords(staff.getAreaId(), staff.getId(), childIds, daily, param);
            List<HLMoreRecord> moreRecords  = moreRecordService.dailyRecords(staff.getAreaId(), staff.getId(), childIds, daily, param);

            Map<String, List<HLFeedingRecord>> feedingRecordsCache = list2CacheMap(feedingRecords);
            Map<String, List<HLSleepRecord>> sleepRecordsCache = list2CacheMap(sleepRecords);
            Map<String, List<HLPottyRecord>> pottyRecordsCache = list2CacheMap(pottyRecords);
            Map<String, List<HLMedicationRecord>> medicationRecordsCache = list2CacheMap(medicationRecords);
            Map<String, List<HLTemperatureRecord>> temperatureRecordsCache = list2CacheMap(temperatureRecords);
            Map<String, List<HLMoreRecord>>  moreRecordsCache= list2CacheMap(moreRecords);

            Page<HLDailyRecordVO> vos = ret.map(o -> {
                HLDailyRecordVO vo = HLDailyRecordVO.of(o);

                vo.setFeedingRecords(feedingRecordsCache.getOrDefault(o.getChildId(), new ArrayList<>()));
                vo.setSleepRecords(sleepRecordsCache.getOrDefault(o.getChildId(), new ArrayList<>()));
                vo.setPottyRecords(pottyRecordsCache.getOrDefault(o.getChildId(), new ArrayList<>()));
                vo.setMedicationRecords(medicationRecordsCache.getOrDefault(o.getChildId(), new ArrayList<>()));
                vo.setTemperatureRecords(temperatureRecordsCache.getOrDefault(o.getChildId(), new ArrayList<>()));
                vo.setMoreRecords(moreRecordsCache.getOrDefault(o.getChildId(), new ArrayList<>()));

                return vo;
            });

            return StatusResponse.success(vos);
        }

        return StatusResponse.success();

//        Page<HLDailyRecordVO> vos = ret.map(o -> {
//            HLDailyRecordVO vo = HLDailyRecordVO.of(o);
//            List<HLFeedingRecord> feedingRecords  = feedingRecordService.dailyRecords(staff.getAreaId(), staff.getId(), o.getChildId(), daily, param);
//            vo.setSleepRecords(sleepRecordService.dailyRecords(staff.getAreaId(), staff.getId(), o.getChildId(), daily, param));
//            vo.setPottyRecords(pottyRecordService.dailyRecords(staff.getAreaId(), staff.getId(), o.getChildId(), daily, param));
//            vo.setFeedingRecords(feedingRecords);
//            vo.setMedicationRecords(medicationRecordService.dailyRecords(staff.getAreaId(), staff.getId(), o.getChildId(), daily, param));
//            vo.setSleepRecords(sleepRecordService.dailyRecords(staff.getAreaId(), staff.getId(), o.getChildId(), daily, param));
//            vo.setTemperatureRecords(temperatureRecordService.dailyRecords(staff.getAreaId(), staff.getId(), o.getChildId(), daily, param));
//
//            return vo;
//        });
//        return StatusResponse.success(vos);
    }

    private <T> Map<String, List<T>> list2CacheMap(List<T> list){
        Map<String, List<T>> result = new HashMap<>();

        for (Object o: list){

            HLCareBaseRecord record = (HLCareBaseRecord) o;

            List<T> cidRecords = result.getOrDefault(record.getChildId(), new ArrayList<>());

            cidRecords.add((T) record);

            result.put(record.getChildId(), cidRecords);
        }

        return result;
    }

    @Override
    @ApiOperation(value = "获取一个对象")
    @GetMapping()
    public StatusResponse get(@RequestHeader(TICKET) String ticket, String childId, String id){
        StaffDTO staff = cache.getStaff(ticket);
        HLDailyRecord dailyRecord = baseService.get(staff.getAreaId(), staff.getId(), childId, id);

        HLDailyRecordVO ret = HLDailyRecordVO.of(dailyRecord);

        Date dailyDate =  DateUtil.parseToDate(dailyRecord.getDaily());
        ret.setSleepRecords(sleepRecordService.dailyRecords(staff.getAreaId(), staff.getId(), childId, dailyDate,null));
        ret.setPottyRecords(pottyRecordService.dailyRecords(staff.getAreaId(), staff.getId(), childId, dailyDate,null));
        ret.setFeedingRecords(feedingRecordService.dailyRecords(staff.getAreaId(), staff.getId(), childId, dailyDate,null));
        ret.setMedicationRecords(medicationRecordService.dailyRecords(staff.getAreaId(), staff.getId(), childId, dailyDate,null));
        ret.setSleepRecords(sleepRecordService.dailyRecords(staff.getAreaId(), staff.getId(), childId, dailyDate,null));
        ret.setMoreRecords(moreRecordService.dailyRecords(staff.getAreaId(), staff.getId(), childId, dailyDate,null));

        return StatusResponse.success(dailyRecord);
    }

    @ApiOperation(value = "获取列表")
    @GetMapping("/list")
    public StatusResponse getList(@RequestHeader(TICKET) String ticket, String childId, PagerQuery pagerQuery){
        StaffDTO staff = cache.getStaff(ticket);

        PageRequest pageRequest = PageRequest.of(pagerQuery.getPageNum(), pagerQuery.getPageSize());

        return StatusResponse.success( baseService.page(staff.getAreaId(), staff.getId(), childId, pageRequest));
    }

    @ApiOperation(value = "推送家长")
    @PostMapping("/grant_parent")
    public StatusResponse grantParent(@RequestHeader(TICKET) String ticket, String dailyRecordId){

        return StatusResponse.success();
    }

    @ApiOperation(value = "撤销推送家长")
    @PostMapping("/revoke_grant")
    public StatusResponse revokeGrantParent(@RequestHeader(TICKET) String ticket, String dailyRecordId){

        return StatusResponse.success();
    }
}
